﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Threading.Tasks;

namespace WpfWordsLearner.ViewModels
{
	public class FileTranslationViewModel : BaseViewModel
	{
		public FileTranslationViewModel()
			: base()
		{ }

		private string fname;
		public string FileName
		{
			get { return fname; }
			set { fname = value; OnPropertyChanged(() => FileName); }
		}

		private List<string> words;
		public List<string> ForTranslation
		{
			get { return words; }
			set { words = value; OnPropertyChanged(() => ForTranslation); }
		}

		private List<string> wordsTranslated;
		public List<string> Translated
		{
			get { return wordsTranslated; }
			set { wordsTranslated = value; OnPropertyChanged(() => Translated); }
		}

		private int wordsCount;
		public int WordsCount
		{
			get { return wordsCount; }
			set { wordsCount = value; OnPropertyChanged(() => WordsCount); }
		}

		private float perc;
		public float Percentages
		{
			get { return perc; }
			set { perc = value; OnPropertyChanged(() => Percentages); }
		}

		private bool siCompl;
		public bool Running
		{
			get { return siCompl; }
			set { siCompl = value; OnPropertyChanged(() => Running); }
		}

		private bool m_useSort;
		public bool UseSort
		{
			get { return m_useSort; }
			set { m_useSort = value; OnPropertyChanged(() => UseSort); }
		}


		public ICommand TranslateCommand { get { return new WpfWordsLearner.Helper.BaseCommand(TranslateExecuted, new Func<bool>(CanTranslate)); } }

		private void TranslateExecuted()
		{
			if (string.IsNullOrEmpty(FileName))
				return;
			ForTranslation = new List<string>();
			if (Translated != null)
			{
				Translated.Clear();
				Translated = null;
			}

			Task translateTask = new Task(new Action(() =>
				{
					Running = true;
					string[] lines = System.IO.File.ReadAllLines(FileName);
					if (lines == null || lines.Length == 0)
						return;

					Parallel.ForEach(lines, line =>
					{
						if (string.IsNullOrEmpty(line) || string.IsNullOrWhiteSpace(line))
							return;
						ForTranslation.Add(line.StartsWith(" ") ? line.TrimStart() : line);
					});

					WordsCount = ForTranslation.Count;

					Translated = new List<string>();

					using (ServiceReferenceTranslater.TranslateServiceClient client = new ServiceReferenceTranslater.TranslateServiceClient())
					{
						Parallel.ForEach(ForTranslation, line =>
						{
							var req = new ServiceReferenceTranslater.TranslationRequest();
							req.Content = line;
							req.FromLanguage = "en";
							req.ToLanguage = "ru";

							var response = client.Translate(req);
							if (response != null)
							{
								line = string.Format("{0} - {1}", response.OriginalText.Trim(), string.IsNullOrEmpty(response.TranslationResult) ?
																								string.Empty : response.TranslationResult.Trim());

								Translated.Add(line);
							}
						});
					}

					ForTranslation.Clear();
					ForTranslation = null;

					if (m_useSort)
					{
						Translated.Sort();
					}

					string translfname = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(FileName), string.Format("{0}_{1}.txt",
						System.IO.Path.GetFileNameWithoutExtension(FileName), "Translated"));

					if (System.IO.File.Exists(translfname))
						System.IO.File.Move(translfname, System.IO.Path.ChangeExtension(translfname, ".backup"));

					using (System.IO.StreamWriter sw = new System.IO.StreamWriter(translfname))
					{
						foreach (string transl in Translated)
						{
							sw.WriteLine(transl);
						}
						sw.Flush();
					}
				}));

			translateTask.ContinueWith(prevTask =>
				{
					Running = false;
					App.Log.Error("Exception occured while translating file", prevTask.Exception.Flatten());
					prevTask.Dispose();
					Translated = null;
				}, TaskContinuationOptions.NotOnRanToCompletion);

			translateTask.ContinueWith(prevTask =>
			{
				OnPropertyChanged(() => Translated);
				Running = false;
				prevTask.Dispose();
			}, TaskContinuationOptions.OnlyOnRanToCompletion);

			translateTask.Start();
		}

		public bool CanTranslate()
		{
			bool result = false;
			try
			{
				using (ServiceReferenceTranslater.TranslateServiceClient client = new ServiceReferenceTranslater.TranslateServiceClient())
				{ }
				result = true;
			}
			catch (System.ServiceModel.EndpointNotFoundException) { result = false; }

			return result;
		}

		public ICommand ChooseCommand { get { return new WpfWordsLearner.Helper.BaseCommand(ChooseExecuted); } }

		private void ChooseExecuted()
		{
			Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog();
			dialog.Filter = "Text file (*.txt)|*.txt";
			if (dialog.ShowDialog() == true)
			{
				FileName = dialog.FileName;
			}
		}
	}
}
